package com.beans.convert;

import com.beans.dto.CarDTO;
import com.beans.dto.DriverDTO;
import com.beans.dto.PartDTO;
import com.beans.vo.CarVO;
import com.beans.vo.DriverVO;
import com.beans.vo.VehicleVO;
import org.mapstruct.*;
import org.mapstruct.factory.Mappers;

import java.util.List;

/**
 * @author wmh
 * @version 1.0 2022/7/7
 * @Description: Car相关的pojo之间的转换
 * 使用步骤
 * 1.引入依赖
 * 2.新建一个抽象类或者接口标注@Mapper
 * 3.写一个转化方法，方法名字是任意的，没有要求
 * 4.获取对象INSTANCE并使用
 * source和target多余的属性对方没有，不会报错
 *
 *默认映射规则：
 * 同类型，同名的属性会自动映射
 * 自动类型转换
 * 1.基本类型和包装类型会自动转换，
 * 2.8种基本类型(及包装类型)和String
 * 3.日期类型和String
 **/
@Mapper(componentModel = "spring")
public abstract class CarConvert {
    public static CarConvert INSTANCE = Mappers.getMapper(CarConvert.class);


    /**
     * carDTO-->carVO
     */
    @Mappings(value = {@Mapping(source = "totalPrice", target = "totalPrice", numberFormat = "#.00"),
            @Mapping(source = "publishDate", target = "publishDate", dateFormat = "yyy-MM-dd HH:mm:ss"),
            //@Mapping(target = "color", ignore=true),--不映射color
            @Mapping(source = "brand",target = "brandName"),
            @Mapping(source = "driverDTO",target = "driverVO")
    })
    public abstract CarVO dto2vo(CarDTO carDTO);

    /**
     * driverDTO--driverVO
     * @param driverDTO
     * @return
     */
    @Mapping(source = "id",target = "driverId")
    @Mapping(source = "name",target = "fullName")
    public abstract DriverVO DriverDTO2DriverVO(DriverDTO driverDTO);

    @AfterMapping //表示mapstruct在调用完自动转换的方法周，会来自动调用本方法
    //@MappingTarget 表示传来的carVO对象是已经赋值过的
    public void dat2voAfter(CarDTO carDTO,@MappingTarget CarVO carVO){
        List<PartDTO> partDTOS = carDTO.getPartDTOS();
        boolean hasPart = partDTOS != null && !partDTOS.isEmpty();
        carVO.setHasPart(hasPart);
    }

    /**
     * 集合批量转换
     * @param
     * @return
     */
    public abstract List<CarVO> dtos2vos(List<CarDTO> carDTOS);

    /**
     *@BeanMapping配置忽略mapstruct的默认映射行为，只映射了Mapping的属性
     */
    //@Mapping(source = "price",target = "price",ignore = true)
    @BeanMapping(ignoreByDefault = true)
    @Mapping(source = "id",target = "id")
    @Mapping(source = "brand",target = "brandName")
    //VehicleVO(id=330, price=null, brandName=品牌)
    public abstract VehicleVO carDTO2vehicleVO(CarDTO carDTO);
    /*@BeanMapping(ignoreByDefault = true)
      @Mapping(source = "id",target = "id")
      @Mapping(source = "brand",target = "brandName")*/
     //brandName修改了，id被覆盖  VehicleVO(id=null, price=null, brandName=迈巴赫)
    @InheritConfiguration  //避免同样的配置写多份
    @Mapping(target = "id",ignore = true)
    public abstract VehicleVO updateVehicleVO(CarDTO carDTO,@MappingTarget VehicleVO vehicleVO);

    /**
     *测试 @InheritInverseConfiguration反向继承
     * 反向反射不要反过来再写一遍，注意：只继承@Mapping注解配置，不继承@BeanMapping
     * name 指定使用哪一个方法的配置，写方法的名字
     */

    //@BeanMapping(ignoreByDefault = true) @Mapping(source = "id",target = "id") @Mapping(source = "brandName",target = "brand")
    //CarDTO(id=999, vin=null, price=0.0, totalPrice=0.0, publishDate=null, brand=别克, partDTOS=null, driverDTO=null, color=null)
    @InheritInverseConfiguration(name = "carDTO2vehicleVO")
    @BeanMapping(ignoreByDefault = true)
    public abstract CarDTO vehicleVO2carDTO(VehicleVO vehicleVO);
}